package com.springboot.demo.lock.user;

import com.springboot.common.lock.Lock;
import com.springboot.common.lock.LockFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.extern.log4j.Log4j2;

/**
 * 用户锁实现类
 *
 * @author supu
 * @date 2019-03-22 17:52
 **/
@Log4j2
public class UserLockImpl implements UserLock {
    private static final Long DEFAULT_TIME_OUT = 5L;
    private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;

    private final LockFactory lockFactory;

    private final List<Lock> locks;

    private final List<Integer> userIds;

    public UserLockImpl(LockFactory lockFactory, List<Integer> userIds) {
        this.lockFactory = lockFactory;
        this.userIds = userIds;
        this.locks = new ArrayList<>(userIds.size());
    }

    @Override
    public void lock() {
        for (Integer userId : userIds) {
            try {
                Lock lock = lockFactory.getLock("user/" + userId);
                boolean isLock = lock.tryLock(DEFAULT_TIME_OUT, DEFAULT_TIME_UNIT);
                log.info("userId : {} 加锁：{}", userId, isLock ? "success" : "failed");
                if (!isLock) {
                    unLock();
                    break;
                }
                // 加锁成功
                locks.add(lock);
            } catch (Exception e) {
                log.error("userId : {} 加锁异常：{}", userId, e);
                // 加锁一个异常，全部回滚
                unLock();
                break;
            }
        }
    }

    @Override
    public void unLock() {
        locks.forEach(lock -> {
            try {
                lock.unLock();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        locks.clear();
    }
}
